package aspects;
import java.io.IOException;

import annotations.Repeat;

public aspect AspectRepeat {
	
	pointcut repeatedMethods(Repeat anno):
     execution(@Repeat * *(..)) && 
     @annotation(anno);
	
	@SuppressWarnings("unchecked")
	Object around(Repeat anno) :  repeatedMethods(anno) {
		Object res = null;
		int retries = anno.retries();
		long interval = anno.interval()*1000;
		boolean infinity = false;
		if (retries == -1)
			infinity = true;
		int i = 0;
		while(infinity || i<retries){
			try {
				res = proceed(anno);
			}catch(Exception e) {
				if(!ExceptionHandlingHelper.shouldHandleException(anno, e))
					throw new RuntimeException(e);
				
				if(e instanceof IOException)
					if(!handleIOException(anno, e))
						return res;
				
				Class myHandlingClass = anno.selfHandling();
				if(!myHandlingClass.equals(Object.class)){
					if(!ExceptionHandlingHelper.invokeSelfHandling(myHandlingClass))
						return res;
				}
				
				System.out.println("Nastapi ponowienie wykonania metody");
				try {
					Thread.sleep(interval);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
			i++;
		}
		return res;
	}
	
	private Boolean handleIOException(Repeat anno, Exception e) {
		// specific actions for IOException
		Class myHandlingClass = anno.selfHandlingIOException();
		if(!myHandlingClass.equals(Object.class)){
			return ExceptionHandlingHelper.invokeSelfHandling(myHandlingClass);
		}
		return true;
	}

}
